/*
--------------------------------------------------------------------------------
				Ak-Lib. 
			 Project       	: Ak-Lib
			 Group         	: Ak-Lib R&D Team
			 Author        	: Ocean.Wang
			 Create Date 	: 05-01-2010
--------------------------------------------------------------------------------
Code Name 	:  A.K 	~v~
Description	:  Yet Another Cross-Platform Lib.
Cautions    	:
--------------------------------------------------------------------------------
Change History:
Version		: 0.1
Building 		: 05/01/10
10-05.01 first draft, build, debug and test.
--------------------------------------------------------------------------------
*/

#include "ak_obj.h"
#include "ak_evt.h"
#include "ak_gears.h"

/* Trace Lvl */
static 	int 			_gTraceLvl_SEvtQ = TRACELVL_NORMAL;
	
int 	SEvtQ_SetTraceLvl(int lvl)
{
	int 	ret = -1;
	
	switch(lvl){
		case TRACELVL_FATAL:
		case TRACELVL_ERROR:
		case TRACELVL_WARNING:
		case TRACELVL_NORMAL:
		case TRACELVL_DEBUG:
		case TRACELVL_ALL:
			_gTraceLvl_SEvtQ = lvl;
			ret = 0;
			break;
		default:
			break;
	}

	return ret;
}

int 	SEvtQ_GetTraceLvl(void)
{
	return  _gTraceLvl_SEvtQ;
}


static 	unsigned long _gStat_EvtPost = 0;
static 	unsigned long _gStat_EvtSche = 0;
static 	unsigned long _gStat_EvtFini = 0;

/* Here Adding the Support for Slab Allocator */
#define _SEVT_SLAB_MEM_PAGE 		0X80000		/*  512K Based */
#define _SEVT_SLAB_MEM_MIN 			256
#define _SEVT_SLAB_MEM_MAX 			0X40000		/* 256K */
#define _SEVT_SLAB_MEM_RATIO 		16

static 	void * _SEvtPool_AllocEx(_t_sEvtPool * pEvtPool, size_t size)
{
	_t_sysMi  	* pMem;

	pMem = NULL;
	if(pEvtPool){
		pMem = (_t_sysMi *)MPool_AllocEx(&(pEvtPool->mPool), size + _SEVT_EX_MI);
		if(pMem == NULL){
			/* Let's Try GC */
			MPool_GC(&(pEvtPool->mPool), 1);
			/* Try Again */
			pMem = (_t_sysMi *)MPool_AllocEx(&(pEvtPool->mPool), size + _SEVT_EX_MI);	
		}
		if(pMem){
			SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_DEBUG, "EvtPool(%p): Alloc(%p)\n", 
						pEvtPool, 
						pMem); 
			pMem += 1;
		}
	}
	return pMem;
}

static 	int 	_SEvtPool_FreeEx(_t_sEvtPool * pEvtPool, _t_sEvent * pEvent)
{
	int 		ret;
	_t_sIE 	  * pIE;
	_t_sIECont* pCont;
	_t_sysMi  * pCheck;
	
	ret = -1;
	if(pEvtPool && pEvent){
		pIE 	= &(pEvent->ie);
		pCont	= &(pIE->cont);
		if(pCont->msg.ptr){
			switch(pCont->mType){
				case _sIE_MT_DYNAMIC:
					/* Here We check if the Event has been Disp */
					pCheck = (_t_sysMi *)((unsigned char *)(pCont->msg.ptr) - _SEVT_EX_MI);
					SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_DEBUG, "EvtPool(%p): Event(%p): -> MsgE(%p) \n", 
								pEvtPool, 
								pEvent,
								pCheck); 
					MPool_FreeEx(&(pEvtPool->mPool), (_t_sysMi *)(pCheck));
					break;
					
				case _sIE_MT_EX:
					/* Here We check if the Event has been Disp */
					pCheck = (_t_sysMi *)((unsigned char *)(pCont->msg.ptr) - _SEVT_EX_MI - _SEVT_EX_EV);
					SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_DEBUG, "EvtPool(%p): Event(%p): -> MsgE(%p) \n", 
								pEvtPool, 
								pEvent,
								pCheck); 
					MPool_FreeEx(&(pEvtPool->mPool), (_t_sysMi *)(pCheck));
					break;
					
				default:
					SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_NORMAL, "EvtPool(%p): Cont(%p): %-4d -> (%p) \n", 
								pEvtPool, 
								pCont, 
								pCont->mType, 
								pCont->msg.ptr); 
					break;
			}
		}
		else{
			SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_NORMAL, "EvtPool(%p): Cont(%p): %-4d -> (%p) \n", 
						pEvtPool, 
						pCont, 
						pCont->mType, 
						pCont->msg.ptr); 
		}
		ret = 0;
	}
	return ret;
}



int 	SEvtPool_InitEx(_t_sEvtPool * pEvtPool, int mPage)
{
	_t_sysMPool 	* pPool;
	_t_sysMHeap 	* pHeap;
	_t_sysMSlot 	* pSlot;
	size_t 	   		* pSlab;
	unsigned int 	mLimit, itSz, slabCnt;
	int 			i, ret;

	ret = -1;
	if(	pEvtPool){
		/* Init the Slab Pool */
		pHeap = &(pEvtPool->mHeap);
		pPool = &(pEvtPool->mPool);
		pSlot = pEvtPool->slots;
		pSlab = pEvtPool->slabs;
		
		/* Calc the Slab Cnt*/
		MSlab_CalcCnt(_SEVT_SLAB_MEM_MIN, _SEVT_SLAB_MEM_MAX, &slabCnt, &itSz);
		
		/*	Calc the Page Limit */
		/* We Judge the Slab & mPage */
		if(mPage > _SEVT_SLAB_MEM_RATIO){
			mPage = _SEVT_SLAB_MEM_RATIO;
		}
		if(mPage <= 0){
			mPage = 2;
		}
		mLimit = slabCnt * _SEVT_SLAB_MEM_PAGE * mPage;
		mLimit	/= MPOOL_PAGESZ;
		mLimit	+= 1;
		
		MHeap_Init(pHeap, mLimit);
		MPool_Init(pPool, pHeap,	_SEVT_SLAB_MEM_PAGE,	
					itSz,		
					1,	(mLimit * MPOOL_PAGESZ)/_SEVT_SLAB_MEM_PAGE,	MPOOL_T_SLAB_GC);
		MSlab_Init(pPool, pSlot,	pSlab,	slabCnt,		_SEVT_SLAB_MEM_MIN, 	sizeof(_t_sEvent));
		/* Prepare */
		for(i=0; i<slabCnt; i++){ 
			MPool_Pre(pPool, i, 1);
		}

		pEvtPool->evtAlloc = (void *(*)())_SEvtPool_AllocEx;
		pEvtPool->evtFree  = (int 	(*)())_SEvtPool_FreeEx;
	}
	return ret;
}


static 	void * _SEvtPool_AllocSi(_t_sEvtPool * pEvtPool, size_t size)
{
	void 	  * pMem;
	
	pMem = NULL;
	if(pEvtPool){
		if(size < pEvtPool->mPool.itSzMax){
			pMem = MPool_AllocSi(&(pEvtPool->mPool));
			if(pMem){
				SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_DEBUG, "EvtPool(%p) Alloc: MsgP(%p)\n", 
							pEvtPool,pMem); 
			}
		}
	}
	return pMem;
}

static 	int 	_SEvtPool_FreeSi(_t_sEvtPool * pEvtPool, _t_sEvent * pEvent)
{
	int 		ret;
	_t_sIE 	  * pIE;
	_t_sIECont* pCont;
	void	  * pCheck;
	
	ret = -1;
	if(pEvtPool && pEvent){
		pIE 	= &(pEvent->ie);
		pCont	= &(pIE->cont);
		if(	(pCont->mType == _sIE_MT_DYNAMIC) && 
			(pCont->msg.ptr)){
			/* Here We check if the Event has been Disp */
			pCheck = (void *)(pCont->msg.ptr);
			SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_DEBUG, "EvtPool(%p) Free: Event(%p) - MsgP(%p)\n", 
						pEvtPool, 
						pEvent, pCont->msg.ptr); 
			#if 0
			_SEvent_Init(pEvent, 0, 0, 0, 0);
			#endif
			MPool_FreeSi(&(pEvtPool->mPool), (pCheck));
		}
		else{
			SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_NORMAL, "EvtPool(%p) Free: Event(%p) - MsgP(%p)\n", 
						pEvtPool, 
						pEvent, pCont->msg.ptr); 
		}
		ret = 0;
	}
	return ret;
}

int 	SEvtPool_InitSi(_t_sEvtPool * pEvtPool, size_t mLimit,  int itSz)
{
	_t_sysMPool 	* pPool;
	_t_sysMHeap 	* pHeap;
	_t_sysMSlot 	* pSlot;
	unsigned int 	pgInit, pgIncr;
	int 			ret;

	ret = -1;
	if(	pEvtPool){
		pHeap = &(pEvtPool->mHeap);
		pPool = &(pEvtPool->mPool);
		pSlot =  (pEvtPool->slots);
		
		/* Init the Pool */
		if(mLimit < 2)
			mLimit = 2;
		pgIncr = mLimit/16;
		if(pgIncr <= 0){
			pgIncr = 1;
		}
		pgInit = mLimit/2;
		if(pgInit <= 0){
			pgInit = 1;
		}
		
		MHeap_Init(pHeap, mLimit);
		MPool_Init(pPool, pHeap,	_SEVT_SLAB_MEM_PAGE,	itSz, 
			pgIncr,	pgInit,	MPOOL_T_SIMP);
		
		/* Init the Slot */
		MPOOL_SET_SLOT(pPool, pSlot);
		MSlot_Init(pSlot, pPool, 0, itSz);
		
		pEvtPool->evtAlloc = (void *(*)())_SEvtPool_AllocSi;
		pEvtPool->evtFree  = (int 	(*)())_SEvtPool_FreeSi;
	}
	return ret;
}




static 	__inline int 	_SEvent_Fini(_t_sEvent * pEvent)
{
	unsigned int 	mType; 	
	_t_sEvtPool * 	pEvtPool;
	
	if(pEvent){
		_gStat_EvtFini += 1;
		/* Check the MType */
		mType = _SEvent_MType(pEvent);
		switch(mType){
			case _sIE_MT_STATIC:
				_SEvent_Init(pEvent, 0, 0, 0, 0);
				break;
				
			case _sIE_MT_DYNAMIC:
				pEvtPool = pEvent->ie.cont.msg.pool;
				if(pEvtPool){
					pEvtPool->evtFree(pEvtPool, pEvent);
				}
				else{
					SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_ERROR, "Event(%p): Invalid Pool.\n", 
								pEvent); 
				}
				break;
				
			default:
				SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_ERROR, "Event(%p): Invalid MType(%u)\n", 
							pEvent, mType); 
				break;
				
		}
	}
	return -1;
}


/* Make Sure the eProc AU is Available */
int 	SEvtQ_Init(_t_sEvtQ * pEvtQ, _t_sEnv * pEnv, _t_cbentry * eProc[_SEvent_Pri_Max], unsigned int ringCnt[_SEvent_Pri_Max])
{
	int 			i, ret;
	unsigned int 	count, batch;
	_t_sEvtRing * 	pRing;
	
	ret = -1;
	if(pEvtQ && pEnv){
		/* Enviorment */
		pEvtQ->pEnv 	= pEnv;
		
		for(i=0; i<_SEvent_Pri_Max; i++){
			pRing = &(pEvtQ->pri[i]);
			count = ringCnt[i];
			
			if(count < (_SEvtRing_Gap * 2)){
				count = (_SEvtRing_Gap * 2);
			}
			
			/* Init the Ring */
			pRing->ring = (_t_sEvent *)SYS_CALLOC(count, sizeof(_t_sEvent));
			if(pRing->ring){
				pRing->count = count;
				pRing->rdIx = 0;
				pRing->wrIx = 0;
				pRing->eStat= 0;
				SYS_INIT_CS(&(pRing->lock));
			
				pRing->wake  = pEnv->wake;
				/* Calc the Batch */
				switch(i){
					case _SEvent_Pri_Critical:
					case _SEvent_Pri_High:
						/* Calc the Batch */
						batch = (count - _SEvtRing_Gap);
						if(batch == 0)
							batch = 1;
						break;

					case _SEvent_Pri_Medium:
						/* Calc the Batch */
						batch = count/4;
						if(batch == 0)
							batch = 1;
						if(batch > _SEvtBat_Max){
							batch = _SEvtBat_Max;
						}
						break;
						
					case _SEvent_Pri_Low:
					default:
						/* Calc the Batch */
						batch = count/8;
						if(batch == 0)
							batch = 1;
						if(batch > _SEvtBat_Max){
							batch = _SEvtBat_Max;
						}
						break;
				}

				/* Set the Batch, EProc */
				pRing->batch = batch;
				_CBENTRY_ASSIGN(&(pRing->eProc), eProc[i]);
			}
		}

		ret = 0;
	}
	return ret;
}


static 	int		_SEvtRing_Sche(_t_sEnv * pEnv, _t_sEvtRing * pRing)
{
	int 				i, count;
	unsigned int 		batch, ringCnt, rdIx;
	_t_cbentry 	  *		eProc;
	_t_sEvent 	  * 	pEvent;
	_t_sObject 	  * 	pObj;
	
	count = 0;
	batch = pRing->batch;
	eProc = &(pRing->eProc);
	if((batch > 0) && (!_SEvtRing_IsEmpty(pRing))){
		count = _SEvtRing_Count(pRing);
		SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_DEBUG, "Sche(%p): %-4d -> %-4u \n", 
					pRing, count, batch); 
		
		if(count > batch){
			count = batch;
		}
		
		/* Add Statistics */
		if(pRing->eStat < count){
			pRing->eStat = count;
		}
		
		/* Retrive the JobNode */
		_gStat_EvtSche += count;

		ringCnt = pRing->count;
		rdIx 	= pRing->rdIx;
		for(i=0; i<count; i++){
			pEvent  = pRing->ring + rdIx;
			/* Step */
			rdIx 	= (rdIx + 1)%ringCnt;
			
			/* Checking the Object */
			if(	pEnv && (pEnv->desc.lookup) && 
				(pObj = pEnv->desc.lookup(pEvent->dstObj, _SEvent_GetType(pEvent))) && 
				(pObj->evtHdl)){
				/* Object Process */
				pObj->evtHdl(pObj, pEvent, NULL);
			}
			else{
				/* Default Process */
				eProc->cbProc(eProc->pArg, eProc->lArg, pEvent);
			}
			/* Fini the Event */
			_SEvent_Fini(pEvent);
		}
		/* Update the RdIx */
		pRing->rdIx = (pRing->rdIx + count)%ringCnt;
		
	}
	
	return count;
}

int		SEvtQ_Sche(_t_sEvtQ * pEvtQ)
{
	_t_sEnv 		* 	pEnv;
	_t_sEvtRing 	* 	pRing;
	int 				i, j, count;

	count = 0;
	if(pEvtQ && (pEnv = pEvtQ->pEnv)){
		/* Event Ring */
		for(i=0; i<_SEvent_Pri_Max; i++){
			/* We Check the Critical - High - Medium - Low */
			for(j=0; j<=i; j++){
				pRing = &(pEvtQ->pri[j]);
				count = _SEvtRing_Sche(pEnv, pRing);
			}
		}
	}
	return count;
}

int		SEvtQ_Peek(_t_sEvtQ * pEvtQ)
{
	_t_sEvtRing 	* 	pRing;
	int 				i, count, total;

	total = 0;
	if(pEvtQ){
		/* Event Ring */
		for(i=0; i<_SEvent_Pri_Max; i++){
			pRing = &(pEvtQ->pri[i]);
			/* We Check the Critical - High - Medium - Low */
			count = _SEvtRing_Count(pRing);
			total += count;
		}
	}
	return total;
}

static 	int 	_SEvtRing_Dump(_t_sEvtRing * pRing, char * outBuf, int bufLen)
{
	int len = 0;

	if(pRing && outBuf && (bufLen > 0)){
		/* Sche Dump */
		len += SYS_SNPRINTF(outBuf + len, bufLen -len, "(Ring: Ring:%-4u - Bat:%-4u - Rd:%-3u - Wr:%-3u):\n",
			pRing->count, pRing->batch, pRing->rdIx, pRing->wrIx);
	}

	return len;
}


int 			SEvtQ_Dump(_t_sEvtQ * pEvtQ, char * outBuf, int bufLen)
{
	_t_sEvtRing * pRing;
	int i, len = 0;
	
	if(pEvtQ && outBuf && (bufLen > 0)){
		/* Event Ring */
		for(i=0; i<_SEvent_Pri_Max; i++){
			pRing = &(pEvtQ->pri[i]);
			len += _SEvtRing_Dump(pRing, outBuf + len, bufLen - len);
		}
	}
	return len;
}


static 	int 	_SEvent_Send(void * pLink, unsigned char * pBuf, int lBuf, unsigned int ipAddr, unsigned short port)
{	
	_t_ioLinkCi 	* 		pIoCi;
	socklen_t 				sockLen;
	S_SOCKET_ADDRIN  		sockAddr;

	if(pLink){
		pIoCi = (_t_ioLinkCi *)pLink;
		if((pIoCi->bSche == _F_YES) && (pIoCi->eUser.state == SOCKST_OK)){
			/* Get Peer Address */
			sockLen = sizeof(S_SOCKET_ADDRIN);
			S_ADDRIN_INIT(sockAddr, ipAddr, port);
			
			/* Just Send Out */
			SockTx_Udp(pIoCi->eUser.fd, pBuf, lBuf, &sockAddr);
			return 0;
		}
		else{
			SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_WARNING, "IuLink(%p): (0x%08x -> %d)\n", 
					pLink,
					ipAddr, 
					port);
		}
	}

	return -1;
	
}

static	int 	_SEvent_SendSg(void * pLink, 
									unsigned char * pHdr, 	int lHdr, 
									unsigned char * pData, 	int lData, 
									unsigned int 	ipAddr, unsigned short port)
{
	_t_ioLinkCi 	* 		pIoCi;
	socklen_t 				sockLen;
	S_SOCKET_ADDRIN  		sockAddr;
	_t_sgbuf 				sgBuf[2];
	
	if(pLink && pHdr && pData){
		pIoCi = (_t_ioLinkCi *)pLink;
		if((pIoCi->bSche == _F_YES) && (pIoCi->eUser.state == SOCKST_OK)){
			/* Get Peer Address */
			sockLen = sizeof(S_SOCKET_ADDRIN);
			S_ADDRIN_INIT(sockAddr, ipAddr, port);


			SGBUF_ASSIGN(&(sgBuf[0]), pHdr,  lHdr);
			SGBUF_ASSIGN(&(sgBuf[1]), pData, lData);
			/* Just Send Out */
			SockTx_UdpSg(pIoCi->eUser.fd, sgBuf, 2, &sockAddr);
			return 0;
		}
		else{
			SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_WARNING, "IuLink(%p): (0x%08x -> %d)\n", 
					pLink,
					ipAddr, 
					port);
		}
	}

	return -1;
}

/* User API:
** Object Post Event
** 1. Sync
** Check the Object's EvtQ, Set the Priority, 
** Check the EvtQ's Env, Call Object->EvtHdl
** 2. ASync
** Check the Object's EvtQ, Set the Priority,
** Check the EvtQ's Env, Call EventQ Put.
*/

static 	int 	_SEvent_Post(_t_sEnv * pEnv, _t_sEvent * pEvent)
{
	_t_ioLinkCi * 	pLink;
	_t_sEvtQ 	* 	pEvtQ;
	_t_sEvtRing * 	pRing;
	_t_sEvent	* 	pClue;
	_u_ipport 	* 	pIPPort;
	int 			i, ret; 

	ret = -1;
	switch(pEnv->desc.ipc){
		case ENV_IPC_EVTQ:
			if((pEvtQ = pEnv->pEvtQ)){
				pRing = pEvtQ->pri + _SEvent_GetPri(pEvent);	/* Priority Ring */
				i = 0;
				SOP_OP_WAIT(_SEvtRing_EnQue(pRing, pClue, pEvent, ret), 
							ret,
							i,
							_SEvtPost_Retry,
							SOP_WAIT_FAST);
			}
			else{
				SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_ERROR, "Event(%p): Invalid Env(%u)'s EvtQ\n", 
							pEvent, pEvent->dstEnv); 
			}
			if(ret != 0){
				/* Fini the Event */
				_SEvent_Fini(pEvent);
			}
			break;
			
		case ENV_IPC_SOCKET:
			pIPPort = &(pEnv->desc.ipPort);
			if((pLink = (pEnv->pLink)) && (_SEvent_MType(pEvent) == _sIE_MT_STATIC)){
				switch(_SEvent_VType(pEvent)){
					case _sIE_VT_NULL:
					case _sIE_VT_S32:
					case _sIE_VT_U32:
					case _sIE_VT_S64:
					case _sIE_VT_U64:
						ret = _SEvent_Send(pLink, (unsigned char *)pEvent, sizeof(_t_sEvent),
								_IPPORT_IP(pIPPort), _IPPORT_PORT(pIPPort));
						break;
				
					case _sIE_VT_MSG:
						if(_SEvent_MsgPtr(pEvent) && (_SEvent_MsgLen(pEvent) > 0)){
							ret = _SEvent_SendSg(pLink, (unsigned char *)pEvent, sizeof(_t_sEvent), 
								(unsigned char *)_SEvent_MsgPtr(pEvent), _SEvent_MsgLen(pEvent),
								_IPPORT_IP(pIPPort), _IPPORT_PORT(pIPPort));
						}
						break;
						
					case _sIE_VT_CACHE:
					case _sIE_VT_CB:
						ret = _SEvent_Send(pLink, (unsigned char *)pEvent, sizeof(_t_sEvent),
								_IPPORT_IP(pIPPort), _IPPORT_PORT(pIPPort));
						break;
					
				
				}
			}
			else{
				SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_ERROR, "Event(%p): Invalid Env(%u)'s Link. MType(%u) : (%p).\n", 
							pEvent, pEvent->dstEnv, _SEvent_MType(pEvent), pLink); 
			}
			#if 0
			/* Fini the Event */
			_SEvent_Fini(pEvent);
			#endif
			break;
			
		default:
			SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_ERROR, "Event(%p): Unknown Dst Env(%u) IPC(%u)\n", 
						pEvent, pEvent->dstEnv, pEnv->desc.ipc); 
			#if 0
			/* Fini the Event */
			_SEvent_Fini(pEvent);
			#endif
			break;
	}
	return ret;
}


int 	SEvent_PostMsg(_t_sEnv * pEnv, _t_sEvent * pIn, void * pMsg, unsigned int lMsg)
{
	_t_sEvtPool	*	pEvtPool;
	void 		* 	pMem;
	unsigned int 	pri;
	int 			ret;

	ret = -1;
	if(pEnv && pIn && ((pri = _SEvent_GetPri(pIn)) < _SEvent_Pri_Max)){
		pEnv = pEnv + pIn->dstEnv;
		
		if(pMsg && (lMsg > 0)){
			/* Dynamic */
			if(pEnv->desc.ipc == ENV_IPC_EVTQ){
				if(	(pEvtPool = pEnv->pEvtPool) && 
					((pMem = pEvtPool->evtAlloc(pEvtPool, lMsg)))){
					/* Init the Cont */
					_SCont_SetMsg(&(pIn->ie.cont), _sIE_MT_DYNAMIC, pMem, lMsg, pEvtPool);
					/* Construct the Msg */
					SYS_MEMCPY(pIn->ie.cont.msg.ptr, pMsg, lMsg);
					_SEvent_MsgLen(pIn) = lMsg;
				}else{
					SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_ERROR, "Event(%p): Alloc Error\n", 
								pIn); 
					return -1;
				}
			}
			/* Static */
			else{
				_SCont_SetMsg(&(pIn->ie.cont), _sIE_MT_STATIC, pMsg, lMsg, NULL);
			}
		}
		else{
			_SIE_SetMType(&(pIn->ie), _sIE_MT_STATIC);
		}
		
		_gStat_EvtPost += 1;
		ret = _SEvent_Post(pEnv, pIn);
		if(ret == -1){
			SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_ERROR, "Event(%p): Env(%p) PostError\n", 
						pIn, pEnv); 
			return -1;
		}
		
	}
	else{
		SYS_TRACE(_gTraceLvl_SEvtQ, TRACELVL_ERROR, "Event(%p): Env(%p) Param Error\n", 
					pIn, pEnv); 
	}	
	return ret;
}

int 	SEnv_Init(_t_sEnv * pEnv, _t_sEnv_Desc * pDesc, _t_sysSemB * pWake, _t_sEvtQ * pEvtQ, _t_sEvtPool * pPool, _t_ioLinkCi * pLink)
{
	if(pEnv && pDesc && pEvtQ && pPool){
		pEnv->desc 	  	= *pDesc; 	
		pEnv->wake 		= pWake;
		pEnv->pEvtQ		= pEvtQ;
		pEnv->pEvtPool 	= pPool;
		pEnv->pLink 	= pLink;
		return 0;
	}
	return -1;
}
